<?php

namespace App\Services\Admin;

use App\Models\ClassBaseInfo;
use App\Models\UserCoupon;
use App\Models\UserSubscribe;
use App\Models\UserSubscribe as UserSubscribeModel;
use App\Models\User as UserModel;
use App\Models\UserTrain;
use App\Models\User as UserModels;
use App\Models\UserVipInfo;
use App\Models\UserVipUseRecord;
use App\Services\Admin\User;
use App\Services\Api\EasyWeChatService;
use App\Services\Api\GoodsServices;
use App\Services\Api\UserRankExpServices;
use Illuminate\Support\Facades\DB;

class UserSubscribeService extends Base
{
    public static function lists($class_base_info_id = 0, $time = 0)
    {
        $input = request()->all();

        $where = [];

        if (!empty($input['user_id'])) $where[] = ['user_id', $input['user_id']];
        if (!empty($input['status'])) $where[] = ['status', 'like', '%' . $input['status'] . '%'];
        if (!empty($input['is_tutoring'])) $where[] = ['is_tutoring', $input['is_tutoring']];
        if (!empty($input['classroom'])) $where[] = ['class_classroom_id', $input['classroom']];
        if (!empty($input['teacher'])) $where[] = ['teacher_id', $input['teacher']];
        if (!empty($input['subscribe_status'])) $where[] = ['subscribe_status', $input['subscribe_status']];
        if (!empty($input['store_id'])) $where[] = ['store_id', $input['store_id']];
        if (!empty($input['class_base'])) $where[] = ['class_base_id', $input['class_base']];
        if (!empty($class_base_info_id)) $where[] = ['class_base_info_id', $class_base_info_id];

        if (!empty($input['start_time']) && !empty($input['end_time'])) {
            $where[] = ['class_time', '>=', $input['start_time']];
            $where[] = ['end_time', '<=', $input['end_time']];
        }

        if (!empty($time)) {
            $start_time_string = "{$time} 00:00:00";
            $end_time_string = "{$time} 23:59:59";
            $where[] = ['class_time', '>=', $start_time_string];
            $where[] = ['end_time', '<=', $end_time_string];
        }

        return (new UserSubscribeModel)->with(['user'])->whereHas('user', function ($query) use ($input) {
            if (!empty($input['sear_value'])) {
                $where[] = ['user_number', 'like', '%' . $input['sear_value'] . '%'];
                $where[] = ['nickname', 'like', '%' . $input['sear_value'] . '%', 'OR'];
                $where[] = ['phone', 'like', '%' . $input['sear_value'] . '%', 'OR'];
                $query->where($where);
            }
        })->where($where)->orderBy('id', 'desc')->paginate(15);
    }

    public static function info($id)
    {
        return (new UserSubscribeModel)->with([
            'user'
        ])->where('id', $id)->first();
    }

    public static function add($param = [])
    {
        return (new UserSubscribeModel)->insert($param);
    }

    public static function edit($id, $param = [])
    {
        UserModel::where('id', $param['user_id'])->update($param);

        return (new UserSubscribeModel)->where('id', $id)->update($param);
    }

    //退出排隊
    public static function return_queue($id)
    {
        //开启事务
        DB::beginTransaction();

        $user_subscr = (new UserSubscribeModel)->where('id', $id);

        $user_subscr_info = $user_subscr->first();

        if ($user_subscr_info->subscribe_status == 3) throw new \Exception('重複操作，請刷新頁面！');

        $user_subscr_info->subscribe_status = 3;
        $user_subscr_info->queue_number = 0;
        $user_subscr_info->save();

        $msg = self::appointment_queue_remark($user_subscr_info, '後臺操作退出排隊');

        if(!empty($user_subscr_info->user_vip_use_record_id)){
            self::appointment_queue_vip_remark($user_subscr_info, '後臺操作退出排隊');
        }else {
            self::cancel_return_consumption($user_subscr_info, $msg);
        }

        $user_info = User::info($user_subscr_info->user_id);

        $data = [
            'character_string1'=>['value'=>$user_info->user_number],            //会员编号
            'thing2'=>['value'=>$user_subscr_info->class_name],                          //課程名稱
            'thing3'=>['value'=>$user_subscr_info->store_name],                          //上课地点
            'time4'=>['value'=>$user_subscr_info->class_time],                           //日期
            'thing5'=>['value'=>'退出排隊'],                                      //預約狀態
        ];

        EasyWeChatService::sendUserMessage($user_subscr_info->user_id, $data);

        DB::commit();
    }

    //取消预约
    public static function cancel_appointment($id)
    {
        //开启事务
        DB::beginTransaction();

        $user_subscr = UserSubscribeModel::sharedLock()->where('id', $id);

        $user_subscr_info = $user_subscr->first();

        if ($user_subscr_info->subscribe_status == 4) throw new \Exception('重複操作，請刷新頁面!');

        $user_subscr->update(['subscribe_status' => 4]);

        if(!empty($user_subscr_info->user_vip_use_record_id)){
            self::appointment_queue_vip_remark($user_subscr_info, '後臺操作取消預約');
        }else {
            $msg = self::appointment_queue_remark($user_subscr_info, '後臺操作取消預約');
            self::cancel_return_consumption($user_subscr_info, $msg);
        }

        $user_info = User::info($user_subscr_info->user_id);

        $data = [
            'character_string1'=>['value'=>$user_info->user_number],            //会员编号
            'thing2'=>['value'=>$user_subscr_info->class_name],                 //課程名稱
            'thing3'=>['value'=>$user_subscr_info->store_name],                 //上课地点
            'time4'=>['value'=>$user_subscr_info->class_time],                  //日期
            'thing5'=>['value'=>'預約取消'],                                      //預約狀態
        ];

        EasyWeChatService::sendUserMessage($user_subscr_info->user_id, $data);

        self::change_all_ranks($user_subscr_info);

        DB::commit();
    }

    /**
     *
     * @param $user_subscr_info
     * @param string $remark
     * @return string
     */
    public static function appointment_queue_remark($user_subscr_info, $remark = '')
    {
        $class_time = $user_subscr_info->class_time;

        $end_time = $user_subscr_info->end_time;

        $time = date("Y-m-d",strtotime($class_time));
        $class_time_h = date("H:i",strtotime($class_time));
        $end_time_h = date("H:i",strtotime($end_time));
        $end_time_string = "{$class_time_h}-{$end_time_h}";

        $use_integral_msg = [
            $remark,
            "+{$user_subscr_info->use_integral}分",
            $time,
            $end_time_string,
            $user_subscr_info->class_name
        ];

        //扣减积分
        $msg = implode("/",$use_integral_msg);

        return $msg;
    }

    /**
     * vip 退出
     * @param $user_subscr_info
     * @param string $remark
     * @return string
     */
    public static function appointment_queue_vip_remark($user_subscr_info, $remark = '')
    {
        $class_time = $user_subscr_info->class_time;

        $end_time = $user_subscr_info->end_time;

        $time = date("Y-m-d",strtotime($class_time));
        $class_time_h = date("H:i",strtotime($class_time));
        $end_time_h = date("H:i",strtotime($end_time));
        $end_time_string = "{$class_time_h}-{$end_time_h}";

        //查詢記錄
        $user_vip_record = (new UserVipUseRecord())->where('id', $user_subscr_info->user_vip_use_record_id)->first();

        $use_integral_msg = [
            $remark,
            "{$user_vip_record->user_vip_name} 會員卡退還使用次數",
            $time,
            $end_time_string,
            $user_subscr_info->class_name
        ];

        //
        $msg = implode("/",$use_integral_msg);

        //操作會員卡退款
        $where_update_vip = [];
        $where_update_vip[] = ['vip_id', $user_vip_record->user_vip_id];
        $where_update_vip[] = ['class_info_id', $user_vip_record->class_info_id];
        $where_update_vip[] = ['is_restriction', 1];

        (new UserVipInfo())->where($where_update_vip)->increment('num');

        //退卡記錄
        if(!empty($user_subscr_info->user_vip_use_record_id)){

            //操作記錄
            $vip_record = [];
            $vip_record['user_id'] = $user_subscr_info->user_id;
            $vip_record['user_vip_id'] = $user_vip_record->user_vip_id;
            $vip_record['user_vip_name'] = $user_vip_record->user_vip_name;
            $vip_record['class_name'] = $user_vip_record->class_name;
            $vip_record['class_info_id'] = $user_vip_record->class_info_id;
            $vip_record['created_at'] = date("Y-m-d H:i:s");
            $vip_record['is_restriction'] = $user_vip_record->is_restriction;

            if(!empty($user_vip_record->is_restriction)) {
                $vip_record['before_num'] = $user_vip_record->after_num;
                $vip_record['after_num'] = ++$user_vip_record->after_num;
            }else{
                $vip_record['before_num'] = 0;
                $vip_record['after_num'] = 0;
            }

            $vip_record['updated_at'] = date("Y-m-d H:i:s");
            $vip_record['remark'] = $remark;
            (new UserVipUseRecord())->insert($vip_record);

        }

        return $msg;
    }

    public static function cancel_return_vip($user_subscr_info, $remark = "", $user_vip_record, $user_id = 0)
    {
        DB::beginTransaction();

        //操作會員卡退款
        $where_update_vip = [];
        $where_update_vip[] = ['vip_id', $user_vip_record->user_vip_id];
        $where_update_vip[] = ['class_info_id', $user_vip_record->class_info_id];
        $where_update_vip[] = ['is_restriction', 1];

        (new UserVipInfo())->where($where_update_vip)->increment('num');

        if(!empty($user_subscr_info->user_vip_use_record_id)){

            //操作記錄
            $vip_record = [];
            $vip_record['user_id'] = $user_id;
            $vip_record['user_vip_id'] = $user_vip_record->user_vip_id;
            $vip_record['user_vip_name'] = $user_vip_record->user_vip_name;
            $vip_record['class_name'] = $user_vip_record->class_name;
            $vip_record['class_info_id'] = $user_vip_record->class_info_id;
            $vip_record['created_at'] = date("Y-m-d H:i:s");
            $vip_record['is_restriction'] = $user_vip_record->is_restriction;
            if(!empty($user_vip_record->is_restriction)) {
                $vip_record['before_num'] = $user_vip_record->after_num;
                $vip_record['after_num'] = ++$user_vip_record->after_num;
            }else{
                $vip_record['before_num'] = 0;
                $vip_record['after_num'] = 0;
            }
            $vip_record['updated_at'] = date("Y-m-d H:i:s");
            $vip_record['remark'] = $remark;
            (new UserVipUseRecord())->insert($vip_record);

        }

        DB::commit();
    }

    /**
     * 退还捆绑卷或者现金卷或者积分支付
     * @param $user_subscr_info
     * @remark 客服備注
     *
     */
    public static function cancel_return_consumption($user_subscr_info, $remark = '')
    {
        DB::beginTransaction();
        if ($user_subscr_info->is_discount == 1) {

            //捆绑卷更新
            $class_base_info_id = $user_subscr_info->class_base_info_id;

            $discount_order_id = $user_subscr_info->discount_order_id;

            $update = [];
            $update['updated_at'] = '';
            $update['status'] = '1';

            (new UserCoupon())->where('class_base_info_id', $class_base_info_id)->where('discount_order_id', $discount_order_id)->update($update);

        } elseif ($user_subscr_info->is_coupon == 1) {

            //现金卷更新
            $user_coupon_id = $user_subscr_info->user_coupon_id;

            $update = [];
            $update['updated_at'] = '';
            $update['status'] = '1';
            $update['class_base_info_id'] = '0';

            (new UserCoupon())->where('id', $user_coupon_id)->update($update);

            if ($user_subscr_info->use_integral > 0) {
                User::record_do($user_subscr_info->user_id, $remark, 1, $user_subscr_info->use_integral);
            }

        } else {

            //积分支付
            if ($user_subscr_info->use_integral > 0) {
                User::record_do($user_subscr_info->user_id, $remark, 1, $user_subscr_info->use_integral);
            }

        }
        DB::commit();
    }

    /**
     * 改变所有排位
     * @param $user_subscr_info
     */
    public static function change_all_ranks($user_subscr_info)
    {
        DB::beginTransaction();

        //下一個上位
        $waitObj = UserSubscribeModel::where('class_base_info_id', $user_subscr_info->class_base_info_id)
            ->where('class_time', $user_subscr_info->class_time)
            ->where('end_time', $user_subscr_info->end_time)
            ->where('subscribe_status', 1)
            ->orderBy('created_at', 'asc')
            ->first();

        //预约数
        $class_subscribe_number = (new UserSubscribe)->ClassSubscribeNumber([$user_subscr_info->class_base_info_id], $user_subscr_info->class_time, $user_subscr_info->end_time,[2]);

        $class_number_people = ClassBaseInfo::where('id', $user_subscr_info->class_base_info_id)->value('class_number_people');

        //判断是否允许让排队的跟上
        $is_queue_up = true;

        $already_booked = $class_subscribe_number[$user_subscr_info->class_base_info_id]??0;

        if ($class_number_people < $already_booked) {
            //超过预约人数不允许
            $is_queue_up = false;
        }

        //dd($waitObj);
        //等于2，3是camp不受预约容纳人数限制，buy_type 受容纳人数限制
        if (!empty($waitObj)) {
            if (($user_subscr_info->buy_type == 1 && $is_queue_up) || in_array($user_subscr_info->buy_type,[2,3])) {
                if($user_subscr_info->subscribe_status == 2 || $user_subscr_info->subscribe_status == 3) {
                    $waitObj->subscribe_status = 2;
                    $waitObj->queue_number = 0;
                    $waitObj->save();

                    //改变所有排位
                    $next_waitObj = UserSubscribeModel::where('class_base_info_id', $user_subscr_info->class_base_info_id)
                        ->where('class_time', $user_subscr_info->class_time)
                        ->where('end_time', $user_subscr_info->end_time)
                        ->where('subscribe_status', 1)
                        ->where('id', '!=', $waitObj->id)
                        ->orderBy('created_at', 'asc')
                        ->get();

                    if (!empty($next_waitObj)) {
                        foreach ($next_waitObj as $kk => $vv) {
                            $queue_number = $vv['queue_number'] - 1;
                            UserSubscribeModel::where('id', $vv['id'])->update(['queue_number' => $queue_number]);
                        }
                    }

                    $user_info = User::info($waitObj->user_id);

                    $data = [
                        'character_string1'=>['value'=>$user_info->user_number],            //会员编号
                        'thing2'=>['value'=>$waitObj->class_name],                          //課程名稱
                        'thing3'=>['value'=>$waitObj->store_name],                          //上课地点
                        'time4'=>['value'=>$waitObj->class_time],                           //日期
                        'thing5'=>['value'=>'預約成功'],                                      //預約狀態
                    ];

                    EasyWeChatService::sendUserMessage($waitObj->user_id, $data);
                }
            }
        }

        DB::commit();
    }

    /**
     * 簽到邏輯
     * @param int $class_base_info_id
     */
    public static function sign_in($user_subscribe_id = 0)
    {
        //开启事务
        DB::beginTransaction();

        $subscribe = (new UserSubscribe())
            ->where('id', $user_subscribe_id)
            ->first();

        if ($subscribe->subscribe_status == 5) throw new \Exception('重複操作，請刷新頁面');

        $user_train = new UserTrain();

        $class_base_info = Reservation::lists()->where('id', $subscribe->class_base_info_id)->first();

        (new GoodsServices())->add_goods_integral($subscribe->user_id, $subscribe->id);

        $res = $user_train->insert([
            'user_id' => $subscribe->user_id,
            'class_base_id' => $class_base_info->class_base->id,
            'teacher_id' => $subscribe->teacher_id,
            'store_id' => $class_base_info->store->id,
            'subscribe_id' => $subscribe->id,
            'class_classroom_id' => $class_base_info->classsroom->id,
            'class_base_info_id' => $subscribe->class_base_info_id,
            'train_time' => (strtotime($subscribe->end_time) - strtotime($subscribe->class_time)) / 60,
            'created_at' => date("Y-m-d H:i:s"),
        ]);

        $subscribe->subscribe_status = 5;

        $subscribe->save();

        (new UserModels())->where('id', $subscribe->user_id)->increment('total_train_time', (strtotime($subscribe->end_time) - strtotime($subscribe->class_time)) / 60);

        $expData = [
            'exp_value' => $subscribe->use_integral,
            'user_id' => $subscribe->user_id,
            'type' => 1,
            'remarks' => '签到积分',
            'created_at' => date("Y-m-d H:i:s")
        ];

        (new UserRankExpServices())->add_user_rank_exp($expData);

        DB::commit();
    }
}
